package com.handinfo.android.core.object;

import java.io.DataInputStream;
import java.io.IOException;

import com.handinfo.android.DWGameManager;
import com.handinfo.android.core.graphics.DWBitmap;
import com.handinfo.android.core.graphics.DWGraphics;
import com.handinfo.android.core.resource.Resource;
import com.handinfo.android.core.resource.ResourceManager;
import com.handinfo.android.utils.Tools;

public class Layer
{
	public static final byte TYPE_IMAGECLIP = 0;
	public static final byte TYPE_SCROLLIMAGE = 1;
	public static final byte TYPE_TILEDLAYER = 2;
	public static final byte TYPE_PHYSICALLAYER = 3;
	public final static byte MOVETYPE_NOMOVE = 0;
	public final static byte MOVETYPE_LINE = 1;
	public final static byte MOVETYPE_CIRCLE = 2;
	public final static byte MOVETYPE_PARABOLA = 3;
	public final static byte CYCLETYPE_NOCYCLE = 0;
	public final static byte CYCLETYPE_CYCLE = 1;
	public final static byte CYCLETYPE_REPEAT = 2;
	public static final byte IC_PARAM_COUNT = 6;
	public static final byte IC_PARAM_FLAG = 0;
	public static final byte IC_PARAM_MOVETYPE = 1;
	public static final byte IC_PARAM_MOVEPARAM1 = 2;
	public static final byte IC_PARAM_MOVEPARAM2 = 3;
	public static final byte IC_PARAM_MOVEPARAM3 = 4;
	public static final byte IC_PARAM_MOVEPARAM4 = 5;
	public static final byte SI_PARAM_COUNT = 2;
	public static final byte SI_PARAM_FLAG = 0;
	public static final byte SI_PARAM_SPEED = 1;

	private Background m_bg;
	public byte m_type;
	public int m_bitmapInx;
	public DWBitmap m_bitmap;

	public boolean m_hasPalette = false; // 是否使用调色板
	public int m_paletteStart; // 调色板起始位置
	public byte[] m_paletteData; // 调色板数据
	public int m_x;
	public int m_y;
	public int m_tempX;
	public int m_tempY;
	public int m_moveFrame;
	public boolean m_isLineGo = true;

	// 用于贴图层
	public int m_flashInterval;
	public int m_flashDuration;
	public int m_flipFlag; // 翻转标识 &0x01则X翻转 &0x02则Y翻转
	public int m_scrollV; // 卷动速率
	public int mXCount, mYCount; // X，Y方向平铺个数

	public short[] m_data; // 背景层数据，三种背景层数据都用一维数组存储
	public byte[] m_phydata; // 物理层数据，如果背景层不是物理层则始终为空

	public Layer(Background bg)
	{
		this.m_bg = bg;
	}

	public int getCollideValue(int x, int y)
	{
		return m_phydata[y * m_bg.m_columns + x];
	}

	/**
	 * 初始化背景层数据
	 * 
	 * @param dis
	 * @throws java.lang.Exception
	 */
	public void load(DataInputStream dis) throws IOException
	{
		m_bitmapInx = dis.readByte();

		m_hasPalette = (dis.readByte() == 1);
		if (m_hasPalette) {
			m_paletteStart = dis.readShort();
			m_paletteData = new byte[dis.readShort()];
			dis.read(m_paletteData);
		}

		m_type = dis.readByte();

		switch (m_type) {
			case TYPE_IMAGECLIP:
			case TYPE_SCROLLIMAGE: {
				m_x = dis.readShort();
				m_y = dis.readShort();
				m_tempX = m_x;
				m_tempY = m_y;
				m_flashInterval = dis.readShort();
				m_flashDuration = dis.readShort();
				int parameterCount = (m_type == TYPE_IMAGECLIP) ? IC_PARAM_COUNT
						: SI_PARAM_COUNT;
				m_data = new short[parameterCount];
				for (int i = 0; i < parameterCount; i++) {
					m_data[i] = dis.readShort();
				}
				break;
			}
			case TYPE_TILEDLAYER: {
				m_data = new short[m_bg.m_columns * m_bg.m_rows];
				for (int i = 0; i < m_data.length; i++) {
					m_data[i] = dis.readShort();
				}
				break;
			}
			case TYPE_PHYSICALLAYER: {
				m_phydata = new byte[m_bg.m_columns * m_bg.m_rows];
				for (int i = 0; i < m_phydata.length; i++) {
					m_phydata[i] = dis.readByte();
				}
				break;
			}
		}
	}

	public void loadImage(Resource res)
	{
		m_bitmap = (DWBitmap) ResourceManager.getInstance().loadResource(res, m_bg.m_refsResHead[m_bitmapInx]);
	}

	/**
	 * 背景层呼吸方法，用于每帧执行
	 */
	public void tick()
	{
		// 如果是单幅整图则处理图像的运动，目前仅此类型有运动
		if (m_type == TYPE_IMAGECLIP) {
			// 直线运动
			if (m_data[IC_PARAM_MOVETYPE] == MOVETYPE_LINE) {
				m_moveFrame++;
				if (m_moveFrame == m_data[IC_PARAM_MOVEPARAM3]) {
					if (m_data[IC_PARAM_MOVEPARAM4] == CYCLETYPE_NOCYCLE) {
						m_moveFrame--;
					}
					else if (m_data[IC_PARAM_MOVEPARAM4] == CYCLETYPE_CYCLE) {
						m_moveFrame = 0;
						m_isLineGo = !m_isLineGo;
					}
					else if (m_data[IC_PARAM_MOVEPARAM4] == CYCLETYPE_REPEAT) {
						m_moveFrame = 0;
					}
				}
				m_x = m_tempX
						+ (m_isLineGo ? m_moveFrame
								* m_data[IC_PARAM_MOVEPARAM1]
								: (m_data[IC_PARAM_MOVEPARAM3] - m_moveFrame)
										* m_data[IC_PARAM_MOVEPARAM1]);
				m_y = m_tempY
						+ (m_isLineGo ? m_moveFrame
								* m_data[IC_PARAM_MOVEPARAM2]
								: (m_data[IC_PARAM_MOVEPARAM3] - m_moveFrame)
										* m_data[IC_PARAM_MOVEPARAM2]);
			}
			// 圆周运动
			// else if (m_data[IC_PARAM_MOVETYPE] == MOVETYPE_CIRCLE) {
			// //现在的圆周运动都是循环的
			// int angle = m_moveFrame > 0 ? m_moveFrame : m_moveFrame + 360;
			// m_x = (short) ( ( (m_tempX << 8) +
			// m_data[IC_PARAM_MOVEPARAM1] * Tools.sineTimes256(angle)) >>
			// 8);
			// m_y = (short) ( ( (m_tempY << 8) +
			// m_data[IC_PARAM_MOVEPARAM1] * Tools.cosineTimes256(angle)) >>
			// 8);
			// m_moveFrame += m_data[IC_PARAM_MOVEPARAM3]; //转角度
			//
			// }
		}
	}

	/**
	 * 绘制背景层 判断背景层类型后分别调用对应的绘制方法，绘制前将判定是否出于闪烁状态
	 * 
	 * @param g
	 * @param viewX
	 * @param viewY
	 */
	public void drawLayer(DWGraphics g, int viewX, int viewY)
	{
		if (m_bitmap == null) {
			return;
		}
		if (m_flashInterval > 0 && m_flashDuration > 0) {
			// 当前帧数除以持续时间和间隔的余数大于持续时间，则不进行绘制
			if (m_bg.m_frameCount % (m_flashInterval + m_flashDuration) >= m_flashDuration) {
				return;
			}
		}
		if (m_type == TYPE_IMAGECLIP) {
			drawImageClip(g, viewX, viewY);
		}
		else if (m_type == TYPE_SCROLLIMAGE) {
			drawScrollImage(g, viewX, viewY);
		}
		// test 临时画物理层
		else if (m_type == TYPE_TILEDLAYER /* || m_type == TYPE_PHYSICALLAYER */) {
			drawTiledLayer(g, viewX, viewY);
		}
	}
	
	public void drawLayer(DWGraphics g, int viewX, int viewY, int viewW, int viewH, float scaleX, float scaleY)
	{
		if (m_bitmap == null) {
			return;
		}
		if (m_flashInterval > 0 && m_flashDuration > 0) {
			// 当前帧数除以持续时间和间隔的余数大于持续时间，则不进行绘制
			if (m_bg.m_frameCount % (m_flashInterval + m_flashDuration) >= m_flashDuration) {
				return;
			}
		}
		if (m_type == TYPE_IMAGECLIP) {
			drawImageClip(g, viewX, viewY, viewW, viewH, scaleX, scaleY);
		}
		else if (m_type == TYPE_SCROLLIMAGE) {
			drawScrollImage(g, viewX, viewY, viewW, viewH, scaleX, scaleY);
		}
		// test 临时画物理层
		else if (m_type == TYPE_TILEDLAYER /* || m_type == TYPE_PHYSICALLAYER */) {
			drawTiledLayer(g, viewX, viewY, viewW, viewH, scaleX, scaleY);
		}
	}

	/**
	 * 绘制单幅背景图层
	 * 
	 * @param g
	 * @param viewX
	 * @param viewY
	 */
	public void drawImageClip(DWGraphics g, int cameraX, int cameraY)
	{
		g.setClip(0, 0, DWGameManager.Screen_Width,
				DWGameManager.Screen_Height);
		int startX = m_x - cameraX;
		int startY = m_y - cameraY;
		boolean isDraw = Tools.collide(m_x, m_y, m_x + m_bitmap.getWidth(), m_y
				+ m_bitmap.getHeight(), cameraX, cameraY, cameraX
				+ m_bg.m_cameraW, cameraY + m_bg.m_cameraH);
		if (isDraw) {
			boolean flipX = (m_data[IC_PARAM_FLAG] & 0x1) != 0;
			boolean flipY = (m_data[IC_PARAM_FLAG] & 0x2) != 0;
			int flag = DWGraphics.trans(flipX, flipY);
			if (flag == 0) {
				g.drawBitmap(m_bitmap.getImage(), startX, startY, DWGraphics.TOP | DWGraphics.LEFT);
			}
			else {
				g.drawRegion(m_bitmap.getImage(), 0, 0, m_bitmap.getWidth(),
						m_bitmap.getHeight(), flag, startX, startY, DWGraphics.TOP | DWGraphics.LEFT);
			}
		}
	}
	
	public void drawImageClip(DWGraphics g, int cameraX, int cameraY, int cameraW, int cameraH, float scaleX, float scaleY)
	{
		g.setClip(0, 0, DWGameManager.Screen_Width,
				DWGameManager.Screen_Height);
		int startX = m_x - cameraX;
		int startY = m_y - cameraY;
		boolean isDraw = Tools.collide(m_x, m_y, m_x + m_bitmap.getWidth(), m_y
				+ m_bitmap.getHeight(), cameraX, cameraY, cameraX
				+ cameraW, cameraY + cameraH);
		if (isDraw) {
			boolean flipX = (m_data[IC_PARAM_FLAG] & 0x1) != 0;
			boolean flipY = (m_data[IC_PARAM_FLAG] & 0x2) != 0;
			int flag = DWGraphics.trans(flipX, flipY);
			g.drawRegion(m_bitmap.getImage(), 0, 0, m_bitmap.getWidth(),
					m_bitmap.getHeight(), flag, startX * scaleX, startY * scaleY, m_bitmap.getWidth() * scaleX,
					m_bitmap.getHeight() * scaleY, DWGraphics.TOP | DWGraphics.LEFT);
		}
	}

	/**
	 * 绘制卷轴背景图层
	 * 
	 * @param g
	 * @param viewX
	 * @param viewY
	 */
	public void drawScrollImage(DWGraphics g, int viewX, int viewY)
	{
		g.setClip(0, 0, DWGameManager.Screen_Width,
				DWGameManager.Screen_Height);
		boolean scrollX = (m_data[SI_PARAM_FLAG] & 0x1) != 0;
		boolean scrollY = (m_data[SI_PARAM_FLAG] & 0x2) != 0;
		short speed = m_data[SI_PARAM_SPEED];
		int width = m_bitmap.getWidth();
		int height = m_bitmap.getHeight();
		if (!scrollX && !scrollY) {
			// 如果横向和纵向都不卷轴则与单幅图片没有区别，直接调用画单幅图片的方法
			drawImageClip(g, viewX, viewY);
			return;
		}

		if (scrollX) { // 如果横向卷轴
			int startX = -((viewX - m_x) * speed / 100);
			while (startX + width <= 0) {
				startX += width;
			}
			// 通过循环来画卷轴背景，只有超出视口才终止循环
			while (startX < m_bg.m_cameraW) {
				int startY = -((viewY - m_y) * speed / 100);
				if (scrollY) { // 如果纵向卷轴
					while (startY + height <= 0) {
						startY += height;
					}
					while (startY < m_bg.m_cameraH) {
						g.drawBitmap(m_bitmap.getImage(), startX, startY, DWGraphics.TOP | DWGraphics.LEFT);
						startY += height;
					}
				}
				else {
					startY = -m_y;
					g.drawBitmap(m_bitmap.getImage(), startX, startY, DWGraphics.TOP | DWGraphics.LEFT);
				}
				startX += width;
			}
		}
		else if (!scrollX && scrollY) { // 如果仅纵向卷轴
			int startX = -((viewX - m_x) * speed / 100);
			int startY = -((viewY - m_y) * speed / 100);
			while (startY + height <= 0) {
				startY += height;
			}
			// 通过循环来画卷轴背景，只有超出视口才终止循环
			while (startY < m_bg.m_cameraH) {
				g.drawBitmap(m_bitmap.getImage(), startX, startY, DWGraphics.TOP | DWGraphics.LEFT);
				startY += height;
			}
		}
	}
	
	public void drawScrollImage(DWGraphics g, int cameraX, int cameraY, int cameraW, int cameraH, float scaleX, float scaleY)
	{
		g.setClip(0, 0, DWGameManager.Screen_Width,
				DWGameManager.Screen_Height);
		boolean scrollX = (m_data[SI_PARAM_FLAG] & 0x1) != 0;
		boolean scrollY = (m_data[SI_PARAM_FLAG] & 0x2) != 0;
		short speed = m_data[SI_PARAM_SPEED];
		int width = m_bitmap.getWidth();
		int height = m_bitmap.getHeight();
		if (!scrollX && !scrollY) {
			// 如果横向和纵向都不卷轴则与单幅图片没有区别，直接调用画单幅图片的方法
			drawImageClip(g, cameraX, cameraY, cameraW, cameraH, scaleX, scaleY);
			return;
		}

		if (scrollX) { // 如果横向卷轴
			int startX = -((cameraX - m_x) * speed / 100);
			while (startX + width <= 0) {
				startX += width;
			}
			// 通过循环来画卷轴背景，只有超出视口才终止循环
			while (startX < cameraW) {
				int startY = -((cameraY - m_y) * speed / 100);
				if (scrollY) { // 如果纵向卷轴
					while (startY + height <= 0) {
						startY += height;
					}
					while (startY < cameraH) {
						g.drawBitmap(m_bitmap.getImage(), startX * scaleX, startY * scaleY, DWGraphics.TOP | DWGraphics.LEFT);
						startY += height;
					}
				}
				else {
					startY = -m_y;
					g.drawBitmap(m_bitmap.getImage(), startX * scaleX, startY * scaleY, DWGraphics.TOP | DWGraphics.LEFT);
				}
				startX += width;
			}
		}
		else if (!scrollX && scrollY) { // 如果仅纵向卷轴
			int startX = -((cameraX - m_x) * speed / 100);
			int startY = -((cameraY - m_y) * speed / 100);
			while (startY + height <= 0) {
				startY += height;
			}
			// 通过循环来画卷轴背景，只有超出视口才终止循环
			while (startY < m_bg.m_cameraH) {
				g.drawBitmap(m_bitmap.getImage(), startX * scaleX, startY * scaleY, DWGraphics.TOP | DWGraphics.LEFT);
				startY += height;
			}
		}
	}
	
	/**
	 * 绘制拼接背景图层 - 不使用缓存的情况
	 * 
	 * @param g
	 * @param viewX
	 * @param viewY
	 */
	public void drawTiledLayer(DWGraphics g, int viewX, int viewY)
	{
		int srcX, srcY;
		int flag;
		short data1;

		int startX = viewX % m_bg.m_tileW != 0 ? -(viewX % m_bg.m_tileW) : 0;
		int startY = viewY % m_bg.m_tileH != 0 ? -(viewY % m_bg.m_tileH) : 0;
		for (int j = viewY / m_bg.m_tileH; j <= (viewY + m_bg.m_cameraH)
				/ m_bg.m_tileH; j++) {
			if (j >= m_bg.m_rows) {
				continue;
			}

			startX = viewX % m_bg.m_tileW != 0 ? -(viewX % m_bg.m_tileW) : 0;
			for (int i = viewX / m_bg.m_tileW; i <= (viewX + m_bg.m_cameraW)
					/ m_bg.m_tileW; i++) {
				if (i >= m_bg.m_columns) {
					continue;
				}

				if (m_type == TYPE_TILEDLAYER) {
					data1 = m_data[j * m_bg.m_columns + i];
				}
				else if (m_type == TYPE_PHYSICALLAYER) {
					data1 = m_phydata[j * m_bg.m_columns + i];
				}
				else {
					data1 = -1;
				}

				if (data1 == -1) {

				}
				else {
					flag = DWGraphics.trans((data1 & 0x4000) != 0,
							(data1 & 0x2000) != 0);
					data1 &= 0xFFF;
					int tileCountPerLine = m_bitmap.getWidth() / m_bg.m_tileW; // tile图片中每行包含的tile个数
					srcX = (data1 % tileCountPerLine) * m_bg.m_tileW;
					srcY = (data1 / tileCountPerLine) * m_bg.m_tileH;
					g.setClip(startX, startY, m_bg.m_tileW, m_bg.m_tileH);
					if (flag == 0) {
						g.drawBitmap(m_bitmap.getImage(), startX - srcX, startY - srcY,
								DWGraphics.LEFT | DWGraphics.TOP);
					}
					else {
						g.drawRegion(m_bitmap.getImage(), srcX, srcY, m_bg.m_tileW,
								m_bg.m_tileH, flag, startX, startY, 0);
					}
				}
				startX += m_bg.m_tileW;
			}
			startY += m_bg.m_tileH;
		}
	}
	
	public void drawTiledLayer(DWGraphics g, int cameraX, int cameraY, int cameraW, int cameraH, float scaleX, float scaleY)
	{
		int srcX, srcY;
		int flag;
		short data1;

		int startX = cameraX % m_bg.m_tileW != 0 ? -(cameraX % m_bg.m_tileW) : 0;
		int startY = cameraY % m_bg.m_tileH != 0 ? -(cameraY % m_bg.m_tileH) : 0;
		for (int j = cameraY / m_bg.m_tileH; j <= (cameraY + cameraH)
				/ m_bg.m_tileH; j++) {
			if (j >= m_bg.m_rows) {
				continue;
			}

			startX = cameraX % m_bg.m_tileW != 0 ? -(cameraX % m_bg.m_tileW) : 0;
			for (int i = cameraX / m_bg.m_tileW; i <= (cameraX + cameraW)
					/ m_bg.m_tileW; i++) {
				if (i >= m_bg.m_columns) {
					continue;
				}

				if (m_type == TYPE_TILEDLAYER) {
					data1 = m_data[j * m_bg.m_columns + i];
				}
				else if (m_type == TYPE_PHYSICALLAYER) {
					data1 = m_phydata[j * m_bg.m_columns + i];
				}
				else {
					data1 = -1;
				}

				if (data1 == -1) {

				}
				else {
					flag = DWGraphics.trans((data1 & 0x4000) != 0,
							(data1 & 0x2000) != 0);
					data1 &= 0xFFF;
					int tileCountPerLine = m_bitmap.getWidth() / m_bg.m_tileW; // tile图片中每行包含的tile个数
					srcX = (data1 % tileCountPerLine) * m_bg.m_tileW;
					srcY = (data1 / tileCountPerLine) * m_bg.m_tileH;
					g.setClip(startX, startY, (int)(m_bg.m_tileW * scaleX), (int)(m_bg.m_tileH * scaleY));
//					if (flag == 0) {
//						g.drawBitmap(m_bitmap.getImage(), startX - srcX, startY - srcY,
//								DWGraphics.LEFT | DWGraphics.TOP);
//					}
//					else {
						g.drawRegion(m_bitmap.getImage(), srcX, srcY, m_bg.m_tileW,
								m_bg.m_tileH, flag, startX * scaleX, startY * scaleY, m_bg.m_tileW * scaleX, m_bg.m_tileH * scaleY, 0);
//					}
				}
				startX += m_bg.m_tileW;
			}
			startY += m_bg.m_tileH;
		}
	}

	/**
	 * 清除资源方法，通常用于游戏状态切换之前调用以腾出内存空间
	 */
	public void dispose()
	{
		m_data = null;
		m_phydata = null;
		if (m_bitmap != null) {
			m_bitmap = null;
		}
	}
}
